#include "GameState.h"

GameState::GameState() : bulletSpeed(20), lastX(0), healthBar(sf::Vector2f(99,20))
{
	zombieTexture.loadFromFile("Assets/Zombie.png");
	zombieTexture.setSmooth(true);
	bulletTexture.loadFromFile("Assets/Bullet.png");
	bulletTexture.setSmooth(true);

	pistolb.loadFromFile("Assets/PistolSound.wav");
	pistol.setBuffer(pistolb);
	pistol.setVolume(50);

	healthBar.setPosition(10,560);
	healthBar.setFillColor(sf::Color(255,0,0));

	crossHairTexture.loadFromFile("Assets/CrossHairs.png");
	crossHairSprite.setTexture(crossHairTexture);
	crossHairSprite.setOrigin(25, 25);
}

void GameState::createZombie(sf::Time& elap)
{
	
	Zombie newzed;
	newzed.setTexture(zombieTexture);
	newzed.setScale(0.2,0.2);
	newzed.setOrigin(125,150);
	newzed.setPosition(10, lastX);
	newzed.health = 100;
	//Zombie speed we chose a random number for speed
	//This way of setting speed will change in the future and is not final
	float k = (rand()%150);
	newzed.speed =  k*elap.asSeconds();
	lastX = lastX + 50;
	zombies.push_back(newzed);
}

void GameState::createBullet(float playerx, float playery, sf::Vector2i mousePos, sf::Vector2f playerPos)
{
	Bullet bullet;
	pistol.play();
	bullet.collided = false;
	bullet.setTexture(bulletTexture);
	bullet.setOrigin(4,4);
	bullet.setPosition(playerx, playery);
	bullet.mPos = mousePos;
	bullet.playerPos = playerPos;
	bullets.push_back(bullet);
}

void GameState::BulletLogic(sf::RenderWindow &window)
{
	for(int i = 0; i < bullets.size(); ++i)
		{	
			sf::Vector2f plrPos = bullets[i].playerPos;
			sf::Vector2i mPos = bullets[i].mPos;
			//Move the bullet
					const float PI = 3.14159265;
					float dxb = mPos.x - plrPos.x;
					float dyb = mPos.y - plrPos.y;
			         float vectorLengthb = sqrt(dxb*dxb + dyb*dyb);

         float DirectionXB = dxb / vectorLengthb;
         float DirectionYB = dyb / vectorLengthb;

		 float VelocityXB = DirectionXB * bulletSpeed;
		 float VelocityYB = DirectionYB * bulletSpeed;
		 bullets[i].move(VelocityXB, VelocityYB);
		 if(bullets[i].collided == false)
		 window.draw(bullets[i]);
		}
}

void GameState::BulletZombieCollision()
{
	for(int f = 0; f< bullets.size(); ++f)
		{
			for(int g = 0; g < zombies.size(); ++g)
			{
				if(Collision::BoundingBoxTest(bullets[f], zombies[g]))
				{
						float z = (rand()%50);
						z = z/10;
					zombies[g].health = zombies[g].health - z;
					bullets[f].collided = true;
					//std::cout << "Dealt " << z << " Damage\n";
				}
			}
		}
}

void GameState::ZombieLogic(sf::RenderWindow &window, Player &player, float k)
{
					for(int j = 0; j < zombies.size(); ++j)
		{
			if(player.getplayerHealth() >= 1) {
			sf::Vector2f position = zombies[j].getPosition();
			sf::Vector2f plrPos = player.getplayerSprite().getPosition();
			//Move the zombie
			const float PI = 3.14159265;
			float dx = plrPos.x - position.x;
			float dy = plrPos.y - position.y;
			         float vectorLength = sqrt(dx*dx + dy*dy);

         float DirectionX = dx / vectorLength;
         float DirectionY = dy / vectorLength;

		 float VelocityX = DirectionX * zombies[j].speed;
		 float VelocityY = DirectionY * zombies[j].speed;
		 zombies[j].move(VelocityX, VelocityY);
		 //rotate the zombie
			float rotation = (atan2(dy, dx)) * 180 / PI + 90;
			zombies[j].setRotation(rotation);
			//Check for zombie collision with player
			if(Collision::BoundingBoxTest(zombies[j], player.getplayerSprite()))
			{
				//std::cout << "Ewwww you touched a zombie, your health is now: \n" << player.getplayerHealth();
				player.setplayerHealth(player.getplayerHealth() - k);
				healthBar.setSize(sf::Vector2f(healthBar.getSize().x - k, 20));
			}
			}
			//Draw the zombie
			if(zombies[j].health >= 1)
			window.draw(zombies[j]);
			else
			{
				zombies[j].setPosition(10000000,1000000);			
			}
		}
}

void GameState::StartGame(sf::RenderWindow& window)
{
	window.setFramerateLimit(60);
	Player player;
	Menu menu(window);
	GameOver gmover;
	//Creating the map.
	Map map = Map("Assets/Test.tmx");
	//healthText.setFont(menu.getFont());
	//healthText.setPosition(700, 100);
	sf::Clock clock;
	window.setMouseCursorVisible(false);
	float damage;
	float k = (rand()%10);
		k = k/10;
	    // run the program as long as the window is open
    while (window.isOpen())
    {
	sf::Time elapsed = clock.restart();
        // check all the window's events that were triggered since the last iteration of the loop
        sf::Event event;
        while (window.pollEvent(event))
        {
            // "close requested" event: we close the window
			switch(event.type) 
			{
			case sf::Event::Closed:
                window.close();

			case sf::Event::KeyPressed:
				
				if (sf::Keyboard::isKeyPressed(sf::Keyboard::Escape))
				{
					window.close();
				}

			case sf::Event::MouseButtonReleased:
				if(event.type == sf::Event::MouseButtonReleased && event.mouseButton.button == sf::Mouse::Left && player.getplayerHealth() >= 1)
                        {
							float degToRad = 0.0174532925;
							float dis = 12;
							float playerDir = player.getplayerSprite().getRotation();

							createBullet(player.getplayerSprite().getPosition().x+dis*cos(playerDir*degToRad),
								player.getplayerSprite().getPosition().y+dis*sin(playerDir*degToRad),
								sf::Mouse::getPosition(window), player.getplayerSprite().getPosition());
                        }
			}
        }

		if(zombies.size() < 10)
		{
			createZombie(elapsed);
			//std::cout << "Creating new zombie\n";
		}

		if (player.getplayerHealth() >= 1)
		{
		player.updatePlayer();
		player.playerLook(window);
		player.inputCheck(elapsed);
		crossHairSprite.setPosition((sf::Vector2f)sf::Mouse::getPosition(window));
		}
		else if (player.getplayerHealth() < 1)
			gmover.Gameover(window);
		window.clear(sf::Color(139,137,137));
        // draw everything here...
        // window.draw(...);

		//Draw map
			map.draw(window);

		//Bullet logic
			BulletLogic(window);
		//Collision between bullet and zombie
			BulletZombieCollision();
		//Zombie logic
			ZombieLogic(window, player, k);
		//Temporary code for drawing the player to do with health
				//if(player.getplayerHealth() >= 1)
		window.draw(player.getplayerSprite());
				window.draw(healthBar);
		window.draw(crossHairSprite);

        // end the current frame
        window.display();
    }

}
